home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
admin
/
linuxcon.000
/
linuxcon
/
linuxconf-1.6
/
userconf
/
groups.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-15
|
5KB
|
263 lines
#include <unistd.h>
#include <grp.h>
#include <sys/stat.h>
#include "../xconf/xconf.h"
#include "../paths.h"
#include "internal.h"
#include "userconf.h"
#include "userconf.m"
#define ETC_GTMP "/etc/gtmp"
static USERCONF_HELP_FILE help_groups("groups");
static CONFIG_FILE f_group (ETC_GROUP,help_groups,CONFIGF_MANAGED
,"root","root",0644);
PUBLIC GROUPS::GROUPS()
{
struct group *p;
while ((p=getgrent())!=NULL){
add (new GROUP(p));
}
endgrent();
rstmodified();
}
PUBLIC GROUPS::~GROUPS()
{
}
/*
Get one GROUP specification of the table or NULL
*/
PUBLIC GROUP *GROUPS::getitem(int no)
{
return (GROUP*)ARRAY::getitem(no);
}
/*
Return the GROUP specification from its name.
Return NULL if not found.
*/
PUBLIC GROUP *GROUPS::getitem(const char *name)
{
GROUP *ret = NULL;
int nbg = getnb();
for (int i=0; i<nbg; i++){
GROUP *grp = getitem(i);
if (strcmp(grp->getname(),name)==0){
ret = grp;
break;
}
}
return ret;
}
/*
Return the gid of a group from its name.
Return -1 if there is no group with this name.
*/
PUBLIC int GROUPS::getgid(const char *name)
{
GROUP *grp = getitem(name);
return grp == NULL ? -1 : grp->getgid();
}
/*
Write the /etc/group file with proper locking
*/
PUBLIC int GROUPS::write()
{
int ret = -1;
FILE *fout = f_group.fopen (ETC_GTMP,"w");
if (fout != NULL){
int nbu = getnb();
for (int i=0; i<nbu; i++){
getitem(i)->write(fout);
}
fclose(fout);
unlink(ETC_GROUP ".OLD");
link(ETC_GROUP, ETC_GROUP ".OLD");
unlink(ETC_GROUP);
link(ETC_GTMP, ETC_GROUP);
unlink(ETC_GTMP);
chmod(ETC_GROUP, 0644);
ret = 0;
}
return ret;
}
/*
Return the name of the group to use when creating new user (default)
*/
PUBLIC const char *GROUPS::getdefault()
{
/* #Specification: userconf / groups / default for creation
The default group is "users". If this group does not
exist. then the group "group" is used. If none of those
group exist, then no default group is proposed to
the user.
*/
/* #todo: userconf / groups and users / default for creation
It is not clear if a default setup should exist such
as /etc/default/useradd and could be edited by userconf.
Currently, we assumed that the default user group is 1.
*/
const char *ret = NULL;
if (getitem("users")!=NULL){
ret = "users";
}else if (getitem("group")!=NULL){
ret = "group";
}
return ret;
}
/*
Get one GROUP specification of the table or NULL from his GID
*/
PUBLIC GROUP *GROUPS::getfromgid(int gid)
{
GROUP *ret = NULL;
int nbg = getnb();
for (int i=0; i<nbg; i++){
GROUP *grp = getitem(i);
if (grp->getgid() == gid){
ret = grp;
break;
}
}
return ret;
}
/*
Allocate an unused group ID.
*/
PUBLIC int GROUPS::getnew()
{
/* #Specification: userconf / groups / group ID allocation
When creating a new group, the group ID may be left
blank. An unused group ID will be allocated. The first
one unused will be allocated.
We assume that a maximum of 1000 group may be configured.
*/
for (int i=1; i<1000; i++){
if (getfromgid(i)==NULL) break;
}
return i;
}
static int cmpbyname (ARRAY_OBJ *o1, ARRAY_OBJ *o2)
{
GROUP *g1 = (GROUP*) o1;
GROUP *g2 = (GROUP*) o2;
return strcmp(g1->getname(),g2->getname());
}
/*
Sort the array of group by name
*/
PUBLIC void GROUPS::sortbyname()
{
sort (cmpbyname);
}
/*
General edition (addition/deletion/correction) of /etc/group
*/
PUBLIC int GROUPS::edit()
{
int ret = -1;
int choice = 0;
USERS users;
sortbyname();
while (1){
int nbg = getnb();
const char **menuopt = (const char**)malloc_err((nbg*2+1)
*sizeof(char*));
const char **ptsort = menuopt;
for (int i=0; i<nbg; i++){
*ptsort++ = getitem(i)->getname();
*ptsort++ = " ";
}
*ptsort = NULL;
MENU_STATUS code = xconf_menu (
MSG_U(T_GROUPS,"User groups")
,MSG_U(I_GROUPS,"You can edit, add, or delete groups")
,help_groups
,NULL
,NULL
,NULL
,MSG_U(I_TOADD,"to add a new definition")
,menuopt,choice);
if (code == MENU_ESCAPE || code == MENU_QUIT){
break;
}else{
GROUP *grp = getitem(menuopt[choice*2]);
if (code == MENU_OK){
int status = grp->edit(users,*this);
if (status != -1){
if (status == 1) remove_del (grp);
write();
ret = 0;
}
}else if (perm_rootaccess(
MSG_R(P_GROUPDB))){
if (code == MENU_ADD){
GROUP *ngrp = new GROUP;
if (ngrp->edit(users,*this)==0){
add (ngrp);
write ();
ret = 0;
}else{
delete ngrp;
}
}
}
}
}
return ret;
}
void groups_edit()
{
GROUPS groups;
groups.edit();
}
/*
Get the ID of a group. Create it if it does not exist.
Return -1 if it was not created.
*/
int group_getcreate (const char *name, const char *reason)
{
GROUPS groups;
int gid = groups.getgid (name);
if (gid == -1){
char buf[1000];
sprintf (buf
,MSG_U(I_GROUPCREATE
,"The group %s does not exist on your\n"
"system. It is needed to %s\n"
"\n"
"Do you want to create it ? (why not)")
,name,reason);
if (xconf_yesno(MSG_U(Q_GROUPCREATE,"Mandatory group creation")
,buf,help_nil) == MENU_YES){
gid = groups.getnew();
GROUP *grp = new GROUP (name,"*",gid,NULL);
groups.add (grp);
groups.write();
}
}
return gid;
}
#ifdef TEST
int main (int argc, char *argv[])
{
groups_edit();
}
#endif